package process

import (
	"Three/project01/chatroom/client/utils"
	"Three/project01/chatroom/common/message"
	"encoding/json"
	"fmt"
	"net"
	"os"
)

type UserProcess struct {
	//字段..
}

func (this *UserProcess) Register(userId int, userPwd, userName string) (err error) {
	//1，连接到服务器
	conn, err := net.Dial("tcp", "localhost:8889")
	if err != nil {
		fmt.Println("net.Dial err=", err)
		return
	}
	//延时关闭
	defer conn.Close()
	//2,准备通过conn发送消息给服务端
	var mes message.Message
	mes.Type = message.RegisterMesType
	//3,创建一个registerMes结构体
	var registerMes message.RegisterMes
	registerMes.User.UserId = userId
	registerMes.User.UserPwd = userPwd
	registerMes.User.UserName = userName
	//4,将registerMes序列化
	data, err := json.Marshal(registerMes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
		return
	}
	//5,把data赋给了mes.Date字段
	mes.Data = string(data)
	//6,将mes序列化
	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
		return
	}
	//创建一个transfer实例
	tf := &utils.Transfer{
		Conn: conn,
	}
	//发送data给服务端
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("注册conn.Write(data) fail", err)
		return
	}
	//处理返回信息
	mes, err = tf.ReadPkg() //mes就是序列化的RegisterResMes
	if err != nil {
		fmt.Println("tool.ReadPkg(conn) err=", err)
		return
	}
	//将mes的data部分反序列化成RegisterResMes
	var registerResMes message.RegisterResMes
	err = json.Unmarshal([]byte(mes.Data), &registerResMes)
	if registerResMes.Code == 200 {
		fmt.Println("注册成功，请重新登录")
		os.Exit(0)
	} else {
		fmt.Println(registerResMes.Error)
		os.Exit(0)
	}
	return
}

//写一个函数完成登录
func (this *UserProcess) Login(userId int, userPwd string) (err error) {
	//下一个就要开始定协议

	//1，连接到服务器
	conn, err := net.Dial("tcp", "localhost:8889")
	if err != nil {
		fmt.Println("net.Dial err=", err)
		return
	}

	//延时关闭
	defer conn.Close()
	//2,准备通过conn发送消息给服务端
	var mes message.Message
	mes.Type = message.LoginMesType
	//3,创建一个LoginMes结构体
	var loginMes message.LoginMes
	loginMes.UserId = userId
	loginMes.UserPwd = userPwd
	//4,将loginMes序列化
	data, err := json.Marshal(loginMes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
		return
	}
	//5,把data赋给了mes.Date字段
	mes.Data = string(data)
	//6,将mes序列化
	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
		return
	}
	//7，这时候data就是我们要发送的信息
	//创建一个transfer实例
	tf := &utils.Transfer{
		Conn: conn,
	}
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("conn.Write(data) fail", err)
		return
	}

	//这里还需要处理服务的返回的消息...

	mes, err = tf.ReadPkg()
	if err != nil {
		fmt.Println("tool.ReadPkg(conn) err=", err)
		return
	}

	//将mes的data部分反序列化成LoginResMes
	var loginResMes message.LoginResMes
	err = json.Unmarshal([]byte(mes.Data), &loginResMes)
	if loginResMes.Code == 200 {
		//初始化CurUser
		CurUser.Conn = conn
		CurUser.UserId = userId
		CurUser.UserStatus = message.UserOnline
		//fmt.Println("登录成功")

		//可以显示当前用户在线列表，遍历loginResMes.UserId
		fmt.Println("当前在线用户列表如下")
		for _, v := range loginResMes.UsersId {

			//如果我们要求不显示自己在线，我们可以增加一个代码
			if v == userId {
				continue
			}

			fmt.Println("用户id:\t", v)
			//完成客户端的 onlineUsers 的初始化
			user := &message.User{
				UserId:     v,
				UserStatus: message.UserOnline,
			}
			onlineUsers[v] = user
		}
		fmt.Printf("\n\n")

		//这里我们还需要在客户端启动一个协程
		//该协程保持和服务的的通信，如果服务的有数据推送给客户端，则接收并显示在客户端终端。
		go serverProcessMes(conn)

		//循环显示我们登录成功后的菜单
		for {
			ShowMenu()
		}
	} else {
		fmt.Println(loginResMes.Error)
	}

	return
}
